/**
 * 1. class的基本用法 继承 和 类型约束 implements
 * 2. class的修饰符 
 *    readonly(只读，不允许修改) 
 *    private(私有属性，只能内部调用) 
 *    protected(给子类和内部调用，外部无法使用) 
 *    public(默认)
 * 3. super原理
 *    父类的prototype.constructor.call
 *    可以调用父类的所有属性/方法
 *    可以给父类的constructor传参
 * 4. 静态方法 static
 *    不用new 直接Class.xxx
 *    切静态方法里面的this只能访问到静态属性
 * 5. get set
*/

// 4. 静态方法示例
// class StadicDemo {
//   static stat: string
//   static fn(stat: string) {
//     this.stat = stat
//   }
// }
// let staticDemo = StadicDemo
// staticDemo.fn('迪迦')

// 5. get set 示例
// class Ref {
//   _value: any
//   constructor(value: any) {
//     this._value = value
//   }
//   get value() {
//     return this._value + '-g'
//   }
//   set value(newVal) {
//     this._value = newVal + '-s'
//   }
// }
// const ref = new Ref('哈哈哈')
// // console.log(ref.value) // 哈哈哈-g
// ref.value = '坏人'
// console.log(ref.value) // 坏人-s-g

interface Options {
  el: string
}
interface VueCls {
  options: Options,
  init(): void
}

interface Vnode {
  tag: string // div section header ...
  text?: string
  children?: Vnode[]
}
// 虚拟dom 简单版
class Dom {
  // 创建节点的方法
  createElement(el: string) {
    return document.createElement(el)
  }
  // 填充文本的方法
  setText(el: HTMLElement, text: string | null) {
    el.textContent = text
  }
  // 渲染函数
  render(data: Vnode) {
    let root = this.createElement(data.tag)
    if(data.text) {
      this.setText(root, data.text)
    }
    if (data.children && Array.isArray(data.children)) {
      data.children.forEach(item => {
        let child = this.render(item)
        root.appendChild(child)
      })
    }
    return root
  }
}

class Vue extends Dom implements VueCls {
  options: Options;
  constructor(options: Options) {
    super()
    this.options = options
    this.init()
  }
  init(): void {
    // 虚拟dom 就是通过js去渲染我们这个真实dom
    let data: Vnode = {
      tag: 'div',
      children: [
        {
          tag: 'section',
          text: '我是子节点1'
        },
        {
          tag: 'section',
          text: '我是子节点2'
        },
        {
          tag: 'section',
          text: '我是子节点3',
          children: [
            {
              tag: 'span',
              text: '我是子节点3-1'
            }
          ]
        }
      ]
    }
    let app = document.querySelector(this.options.el)
    app?.appendChild(this.render(data))
  }
}
new Vue({
  el: '#app'
})